<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS3 过渡与动画</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            margin: 0;
            padding: 20px;
            color: #333;
        }
        h1 {
            color: #0066cc;
            border-bottom: 2px solid #0066cc;
            padding-bottom: 10px;
        }
        h2 {
            color: #0099cc;
            margin-top: 30px;
        }
        h3 {
            color: #00aadd;
        }
        .example {
            background-color: #f5f5f5;
            border-left: 4px solid #0066cc;
            padding: 15px;
            margin: 20px 0;
            border-radius: 0 4px 4px 0;
        }
        .code {
            background-color: #f8f8f8;
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 15px;
            margin: 15px 0;
            overflow-x: auto;
            font-family: Consolas, Monaco, 'Andale Mono', monospace;
        }
        .note {
            background-color: #ffffd9;
            border-left: 4px solid #ffcc00;
            padding: 15px;
            margin: 20px 0;
            border-radius: 0 4px 4px 0;
        }
        .preview {
            border: 1px solid #ddd;
            padding: 20px;
            margin: 15px 0;
            border-radius: 4px;
            background-color: #fff;
        }
        table {
            border-collapse: collapse;
            width: 100%;
            margin: 20px 0;
        }
        th, td {
            border: 1px solid #ddd;
            padding: 8px 12px;
            text-align: left;
        }
        th {
            background-color: #f2f2f2;
        }
        nav {
            background-color: #f8f8f8;
            padding: 10px;
            margin-bottom: 20px;
            border-radius: 4px;
        }
        nav a {
            margin-right: 15px;
            text-decoration: none;
            color: #0066cc;
        }
        nav a:hover {
            text-decoration: underline;
        }
        /* 演示用样式 */
        .demo-container {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            margin: 20px 0;
        }
        .demo-box {
            width: 100px;
            height: 100px;
            background-color: #0099cc;
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            margin: 20px;
        }
        .demo-item {
            display: flex;
            flex-direction: column;
            align-items: center;
            margin-bottom: 20px;
        }
        .demo-label {
            margin-top: 10px;
            font-size: 14px;
            text-align: center;
        }
        /* 过渡演示 */
        .transition-simple {
            transition: background-color 0.5s ease;
        }
        .transition-simple:hover {
            background-color: #ff9900;
        }
        .transition-multiple {
            transition: background-color 0.5s ease,
                        transform 0.5s ease-in-out;
        }
        .transition-multiple:hover {
            background-color: #ff9900;
            transform: scale(1.2) rotate(10deg);
        }
        .transition-delay {
            transition: background-color 0.5s ease 0.2s,
                        transform 0.5s ease-in-out 0.4s;
        }
        .transition-delay:hover {
            background-color: #ff9900;
            transform: scale(1.2) rotate(10deg);
        }
        /* 动画演示 */
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
        @keyframes slideIn {
            from { transform: translateX(-100%); }
            to { transform: translateX(0); }
        }
        @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.2); }
            100% { transform: scale(1); }
        }
        @keyframes colorChange {
            0% { background-color: #0099cc; }
            25% { background-color: #ff9900; }
            50% { background-color: #cc0066; }
            75% { background-color: #00cc66; }
            100% { background-color: #0099cc; }
        }
        @keyframes bounce {
            0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
            40% { transform: translateY(-30px); }
            60% { transform: translateY(-15px); }
        }
        @keyframes rotate3D {
            0% { transform: rotate3d(1, 1, 1, 0deg); }
            100% { transform: rotate3d(1, 1, 1, 360deg); }
        }
        .animation-fade {
            animation: fadeIn 2s ease-in-out;
        }
        .animation-slide {
            animation: slideIn 1s ease-out;
        }
        .animation-pulse {
            animation: pulse 2s ease-in-out infinite;
        }
        .animation-color {
            animation: colorChange 8s linear infinite;
        }
        .animation-bounce {
            animation: bounce 2s ease infinite;
        }
        .animation-rotate {
            animation: rotate3D 3s linear infinite;
            perspective: 500px;
        }
        .animation-fill-forwards {
            animation: slideIn 2s ease-out forwards;
            position: relative;
            left: -50px;
        }
        .animation-direction {
            animation: pulse 2s ease-in-out infinite alternate;
        }
        .animation-play-state {
            animation: pulse 2s ease-in-out infinite;
        }
        .animation-play-state:hover {
            animation-play-state: paused;
        }
        /* 计时函数演示 */
        .timing-linear {
            transition: transform 1s linear;
        }
        .timing-ease {
            transition: transform 1s ease;
        }
        .timing-ease-in {
            transition: transform 1s ease-in;
        }
        .timing-ease-out {
            transition: transform 1s ease-out;
        }
        .timing-ease-in-out {
            transition: transform 1s ease-in-out;
        }
        .timing-cubic-bezier {
            transition: transform 1s cubic-bezier(0.68, -0.55, 0.27, 1.55);
        }
        .timing-demo:hover {
            transform: translateX(100px);
        }
    </style>
</head>
<body>
    <nav>
        <a href="index.html">首页</a>
        <a href="css3-selectors.html">CSS选择器</a>
        <a href="css3-box-model.html">盒模型</a>
        <a href="css3-layout-flexbox.html">Flexbox布局</a>
        <a href="css3-layout-grid.html">Grid布局</a>
        <a href="css3-colors-gradients.html">颜色与渐变</a>
        <a href="css3-transforms.html">变换</a>
        <a href="css3-transitions-animations.html">过渡与动画</a>
        <a href="css3-responsive.html">响应式设计</a>
    </nav>

    <h1>CSS3 过渡与动画</h1>
    
    <section>
        <h2>CSS3 过渡（Transitions）</h2>
        <div class="example">
            <p>CSS3 过渡允许在指定的时间内平滑地改变属性值，而不是立即改变。过渡通常在某个事件触发时发生，如鼠标悬停、获得焦点或点击。</p>
            
            <h3>过渡属性</h3>
            <div class="code">
                /* 单独设置各个过渡属性 */
                transition-property: background-color;  /* 指定应用过渡效果的 CSS 属性 */
                transition-duration: 0.5s;              /* 过渡持续时间 */
                transition-timing-function: ease;       /* 过渡计时函数 */
                transition-delay: 0.2s;                 /* 过渡延迟时间 */
                
                /* 简写形式 */
                transition: background-color 0.5s ease 0.2s;
                
                /* 应用于多个属性 */
                transition: background-color 0.5s ease,
                           transform 1s ease-in-out;
                
                /* 应用于所有可过渡属性 */
                transition: all 0.5s ease;
            </div>
            
            <div class="demo-container">
                <div class="demo-item">
                    <div class="demo-box transition-simple">悬停</div>
                    <div class="demo-label">简单过渡</div>
                </div>
                <div class="demo-item">
                    <div class="demo-box transition-multiple">悬停</div>
                    <div class="demo-label">多属性过渡</div>
                </div>
                <div class="demo-item">
                    <div class="demo-box transition-delay">悬停</div>
                    <div class="demo-label">延迟过渡</div>
                </div>
            </div>
            
            <h3>可过渡的属性</h3>
            <p>大多数数值型属性都可以过渡，包括：</p>
            <ul>
                <li>颜色属性（color, background-color, border-color 等）</li>
                <li>位置属性（top, right, bottom, left, margin, padding 等）</li>
                <li>尺寸属性（width, height, font-size 等）</li>
                <li>变换属性（transform）</li>
                <li>透明度（opacity）</li>
                <li>阴影（box-shadow, text-shadow）</li>
            </ul>
            <p>不可过渡的属性包括：display, position, font-family 等。</p>
            
            <h3>过渡计时函数</h3>
            <div class="code">
                transition-timing-function: linear;        /* 匀速 */
                transition-timing-function: ease;          /* 默认值，慢-快-慢 */
                transition-timing-function: ease-in;       /* 慢-快 */
                transition-timing-function: ease-out;      /* 快-慢 */
                transition-timing-function: ease-in-out;   /* 慢-快-慢（比 ease 更明显） */
                transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);  /* 自定义 */
                transition-timing-function: step-start;    /* 直接跳到结束状态 */
                transition-timing-function: step-end;      /* 保持开始状态直到结束 */
                transition-timing-function: steps(5, end); /* 分 5 步完成 */
            </div>
            
            <div class="demo-container">
                <div class="demo-item">
                    <div class="demo-box timing-linear timing-demo">悬停</div>
                    <div class="demo-label">linear</div>
                </div>
                <div class="demo-item">
                    <div class="demo-box timing-ease timing-demo">悬停</div>
                    <div class="demo-label">ease</div>
                </div>
                <div class="demo-item">
                    <div class="demo-box timing-ease-in timing-demo">悬停</div>
                    <div class="demo-label">ease-in</div>
                </div>
                <div class="demo-item">
                    <div class="demo-box timing-ease-out timing-demo">悬停</div>
                    <div class="demo-label">ease-out</div>
                </div>
                <div class="demo-item">
                    <div class="demo-box timing-ease-in-out timing-demo">悬停</div>
                    <div class="demo-label">ease-in-out</div>
                </div>
                <div class="demo-item">
                    <div class="demo-box timing-cubic-bezier timing-demo">悬停</div>
                    <div class="demo-label">cubic-bezier</div>
                </div>
            </div>
        </div>
        
        <div class="note">
            <p><strong>过渡的局限性：</strong> 过渡只能定义开始状态和结束状态，不能定义中间状态。过渡通常需要触发事件（如悬停）才能开始。如果需要更复杂的动画效果或自动播放，应使用 CSS 动画。</p>
        </div>
    </section>
    
    <section>
        <h2>CSS3 动画（Animations）</h2>
        <div class="example">
            <p>CSS3 动画允许创建更复杂的动画效果，可以定义多个关键帧，并且可以自动播放，不需要触发事件。</p>
            
            <h3>@keyframes 规则</h3>
            <div class="code">
                /* 基本语法 */
                @keyframes animation-name {
                    from { /* 起始状态 */ }
                    to { /* 结束状态 */ }
                }
                
                /* 或者使用百分比 */
                @keyframes animation-name {
                    0% { /* 起始状态 */ }
                    50% { /* 中间状态 */ }
                    100% { /* 结束状态 */ }
                }
                
                /* 示例：淡入动画 */
                @keyframes fadeIn {
                    from { opacity: 0; }
                    to { opacity: 1; }
                }
                
                /* 示例：脉动动画 */
                @keyframes pulse {
                    0% { transform: scale(1); }
                    50% { transform: scale(1.2); }
                    100% { transform: scale(1); }
                }
            </div>
            
            <h3>动画属性</h3>
            <div class="code">
                /* 单独设置各个动画属性 */
                animation-name: fadeIn;              /* 动画名称（对应 @keyframes 规则） */
                animation-duration: 2s;              /* 动画持续时间 */
                animation-timing-function: ease;     /* 动画计时函数 */
                animation-delay: 0.5s;              /* 动画延迟时间 */
                animation-iteration-count: 3;        /* 动画重复次数 */
                animation-direction: alternate;      /* 动画方向 */
                animation-fill-mode: forwards;       /* 动画填充模式 */
                animation-play-state: running;       /* 动画播放状态 */
                
                /* 简写形式 */
                animation: fadeIn 2s ease 0.5s 3 alternate forwards;
                
                /* 应用多个动画 */
                animation: fadeIn 2s ease, slideIn 1s ease-out;
            </div>
            
            <div class="demo-container">
                <div class="demo-item">
                    <div class="demo-box animation-fade">淡入</div>
                    <div class="demo-label">fadeIn</div>
                </div>
                <div class="demo-item">
                    <div class="demo-box animation-slide">滑入</div>
                    <div class="demo-label">slideIn</div>
                </div>
                <div class="demo-item">
                    <div class="demo-box animation-pulse">脉动</div>
                    <div class="demo-label">pulse (无限)</div>
                </div>
                <div class="demo-item">
                    <div class="demo-box animation-color">变色</div>
                    <div class="demo-label">colorChange (无限)</div>
                </div>
                <div class="demo-item">
                    <div class="demo-box animation-bounce">弹跳</div>
                    <div class="demo-label">bounce (无限)</div>
                </div>
                <div class="demo-item">
                    <div class="demo-box animation-rotate">旋转</div>
                    <div class="demo-label">rotate3D (无限)</div>
                </div>
            </div>
            
            <h3>动画迭代次数</h3>
            <div class="code">
                animation-iteration-count: 1;        /* 默认值，播放一次 */
                animation-iteration-count: 3;        /* 播放三次 */
                animation-iteration-count: infinite; /* 无限循环播放 */
            </div>
            
            <h3>动画方向</h3>
            <div class="code">
                animation-direction: normal;          /* 默认值，正向播放 */
                animation-direction: reverse;         /* 反向播放 */
                animation-direction: alternate;       /* 交替播放（奇数次正向，偶数次反向） */
                animation-direction: alternate-reverse; /* 交替播放（奇数次反向，偶数次正向） */
            </div>
            
            <div class="demo-container">
                <div class="demo-item">
                    <div class="demo-box animation-direction">交替</div>
                    <div class="demo-label">alternate</div>
                </div>
            </div>
            
            <h3>动画填充模式</h3>
            <div class="code">
                animation-fill-mode: none;           /* 默认值，动画结束后回到初始状态 */
                animation-fill-mode: forwards;       /* 动画结束后保持最后一帧的状态 */
                animation-fill-mode: backwards;      /* 动画开始前应用第一帧的状态 */
                animation-fill-mode: both;           /* 同时应用 forwards 和 backwards */
            </div>
            
            <div class="demo-container">
                <div class="demo-item">
                    <div class="demo-box animation-fill-forwards">forwards</div>
                    <div class="demo-label">forwards</div>
                </div>
            </div>
            
            <h3>动画播放状态</h3>
            <div class="code">
                animation-play-state: running;       /* 默认值，动画正在播放 */
                animation-play-state: paused;        /* 动画暂停 */
            </div>
            
            <div class="demo-container">
                <div class="demo-item">
                    <div class="demo-box animation-play-state">悬停暂停</div>
                    <div class="demo-label">play-state</div>
                </div>
            </div>
        </div>
        
        <div class="note">
            <p><strong>动画 vs. 过渡：</strong> 动画比过渡更强大，可以定义多个关键帧，可以自动播放，可以控制重复次数和方向。过渡更简单，适合简单的状态变化，通常需要触发事件才能开始。</p>
        </div>
    </section>
    
    <section>
        <h2>性能优化</h2>
        <div class="example">
            <h3>使用硬件加速</h3>
            <div class="code">
                /* 触发硬件加速的属性 */
                transform: translateZ(0);       /* 使用 3D 变换触发硬件加速 */
                will-change: transform;         /* 提前告知浏览器元素将要变化 */
            </div>
            <p>某些 CSS 属性的动画比其他属性更高效。变换（transform）和透明度（opacity）通常是最高效的，因为它们可以利用 GPU 加速。</p>
            
            <h3>避免昂贵的属性</h3>
            <p>尽量避免动画改变布局或触发重绘的属性，如：</p>
            <ul>
                <li>width, height, margin, padding（触发布局计算）</li>
                <li>border-radius, box-shadow（触发复杂的绘制）</li>
                <li>position, display, float（触发布局计算）</li>
            </ul>
            <p>尽可能使用 transform 和 opacity 来实现动画效果。</p>
            
            <h3>使用 will-change 属性</h3>
            <div class="code">
                /* 提前告知浏览器哪些属性将要变化 */
                will-change: transform, opacity;
            </div>
            <p>will-change 属性可以提前告知浏览器元素将要发生变化，让浏览器有机会进行优化。但不要过度使用，只在真正需要的元素上使用。</p>
        </div>
    </section>
    
    <section>
        <h2>实际应用示例</h2>
        <div class="example">
            <h3>按钮悬停效果</h3>
            <div class="code">
                .button {
                    padding: 10px 20px;
                    background-color: #0066cc;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    transition: all 0.3s ease;
                }
                
                .button:hover {
                    background-color: #0055aa;
                    transform: translateY(-3px);
                    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
                }
                
                .button:active {
                    transform: translateY(0);
                    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
                }
            </div>
            
            <h3>加载动画</h3>
            <div class="code">
                @keyframes spin {
                    0% { transform: rotate(0deg); }
                    100% { transform: rotate(360deg); }
                }
                
                .loader {
                    width: 40px;
                    height: 40px;
                    border: 4px solid #f3f3f3;
                    border-top: 4px solid #0066cc;
                    border-radius: 50%;
                    animation: spin 1s linear infinite;
                }
            </div>
            
            <h3>页面元素淡入</h3>
            <div class="code">
                @keyframes fadeInUp {
                    from {
                        opacity: 0;
                        transform: translateY(20px);
                    }
                    to {
                        opacity: 1;
                        transform: translateY(0);
                    }
                }
                
                .fade-in-element {
                    animation: fadeInUp 0.6s ease-out forwards;
                }
                
                /* 为多个元素设置不同的延迟 */
                .fade-in-element:nth-child(1) { animation-delay: 0.1s; }
                .fade-in-element:nth-child(2) { animation-delay: 0.2s; }
                .fade-in-element:nth-child(3) { animation-delay: 0.3s; }
            </div>
            
            <h3>汉堡菜单动画</h3>
            <div class="code">
                .hamburger {
                    width: 30px;
                    height: 20px;
                    position: relative;
                    cursor: pointer;
                }
                
                .hamburger span {
                    display: block;
                    position: absolute;
                    height: 3px;
                    width: 100%;
                    background: #333;
                    border-radius: 3px;
                    transition: all 0.3s ease-in-out;
                }
                
                .hamburger span:nth-child(1) { top: 0; }
                .hamburger span:nth-child(2) { top: 8px; }
                .hamburger span:nth-child(3) { top: 16px; }
                
                .hamburger.active span:nth-child(1) {
                    transform: rotate(45deg);
                    top: 8px;
                }
                
                .hamburger.active span:nth-child(2) {
                    opacity: 0;
                }
                
                .hamburger.active span:nth-child(3) {
                    transform: rotate(-45deg);
                    top: 8px;
                }
            </div>
            
            <h3>图片轮播</h3>
            <div class="code">
                @keyframes slide {
                    0% { transform: translateX(0); }
                    25% { transform: translateX(0); }
                    30% { transform: translateX(-100%); }
                    50% { transform: translateX(-100%); }
                    55% { transform: translateX(-200%); }
                    75% { transform: translateX(-200%); }
                    80% { transform: translateX(-300%); }
                    100% { transform: translateX(-300%); }
                }
                
                .slider {
                    width: 100%;
                    overflow: hidden;
                }
                
                .slider-container {
                    display: flex;
                    width: 400%;
                    animation: slide 20s infinite;
                }
                
                .slide {
                    width: 25%;
                }
            </div>
        </div>
    </section>
    
    <section>
        <h2>过渡与动画的最佳实践</h2>
        <ul>
            <li>优先使用 transform 和 opacity 属性进行动画，它们性能最好</li>
            <li>对于简单的状态变化，使用过渡；对于复杂的动画序列，使用关键帧动画</li>
            <li>避免同时动画过多元素，这会导致性能问题</li>
            <li>为动画设置适当的持续时间：100-300ms 用于快速反馈，300-500ms 用于中等变化，500ms+ 用于更大的变化</li>
            <li>使用 will-change 属性提前告知浏览器将要变化的属性，但不要过度使用</li>
            <li>考虑可访问性，为有前庭功能障碍的用户提供减少动画的选项（prefers-reduced-motion 媒体查询）</li>
            <li>测试动画在不同设备和浏览器上的性能</li>
        </ul>
    </section>
    
    <section>
        <h2>响应式动画</h2>
        <div class="example">
            <h3>使用媒体查询调整动画</h3>
            <div class="code">
                /* 在大屏幕上使用更复杂的动画 */
                @media (min-width: 768px) {
                    .element {
                        animation: complexAnimation 1s ease;
                    }
                }
                
                /* 在小屏幕上使用简单的动画或禁用动画 */
                @media (max-width: 767px) {
                    .element {
                        animation: simpleAnimation 0.5s ease;
                    }
                }
            </div>
            
            <h3>尊重用户偏好</h3>
            <div class="code">